﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using JESAI.Application.Abstractions;
using JESAI.Application.Abstractions.Auth;
using JESAI.Application.Abstractions.Auth.Dtos;
using JESAI.Application.Abstractions.Sys;
using JESAI.Caching;
using JESAI.Core;
using JESAI.Core.Exceptions;
using JESAI.Core.Util.Extensions;
using JESAI.Core.Util.Helpers;
using JESAI.Framework.Filters;
using SqlSugar;
using System.Linq;
using System.Threading.Tasks;

namespace Bucket.Admin.Web.Controllers
{
    /// <summary>
    /// 账户登录
    /// </summary>
    [ApiController]
    [IgnoreResultHandlerAttribute]
    public class AuthController : ControllerBase
    {
        private readonly CacheManager _cacheManager;
        private readonly IAuthService _authService;
        private IUser _user;
        private readonly ILoginService _loginService;

        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="sqlSugarDbContextFactory"></param>
        /// <param name="user"></param>
        /// <param name="cachingProviderFactory"></param>
        /// <param name="authService"></param>
        public AuthController(IAuthService authService, IUser user, ILoginService loginService, CacheManager cacheManager)
        {         
            _authService = authService;
            _user = user;
            _loginService= loginService;
            _cacheManager= cacheManager;
        }

        /// <summary>
        /// 账户登陆 - 密码登陆
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/Account/Login")]
        public async Task<dynamic> LoginAsync([FromBody] LoginInput input)
        {
            // 用户验证
            if (!_cacheManager.Exits($"ImgCode_{input.ImgCode.ToLower()}"))
                throw new Exception("验证码错误!");
            else
                _cacheManager.Del($"ImgCode_{input.ImgCode.ToLower()}");
            var userInfo = _loginService.GetUserInfoByUserName(input.UserName);
            if (userInfo == null)
                throw new Exception("账号不存在");
            if (userInfo.State != 1)
                throw new Exception("账号状态异常");
            if (userInfo.Password != Encrypt.SHA256(input.Password + userInfo.Salt))
                throw new Exception("账号或密码错误");
            // 用户角色
            var roleList=_loginService.GetUserRoleByUserId(userInfo.Id);         
            // token返回
            var token = _authService.CreateAccessToken(new UserTokenDto
            {
                Email = userInfo.Email,
                Id = userInfo.Id,
                Mobile = userInfo.Mobile,
                RealName = userInfo.RealName,
                Ids = userInfo.Id.ToString()
            }, roleList.Select(it => it.Key).ToList());
            var loginOutPut = new LoginOutput
            {
                Data = new
                {
                    AccessToken = $"Bearer {token}",
                    Expire = _authService.GetExpireInValue(4),
                    RealName = userInfo.RealName.SafeString(),
                    Mobile = userInfo.Mobile.SafeString(),
                    userInfo.Id
                }
            };
            return loginOutPut;
        }

        /// <summary>
        /// 刷新token
        /// </summary>
        /// <returns></returns>
        [HttpGet("/Account/RefreshToken")]
        [Authorize("permission")]
        public LoginOutput RefreshToken()
        {
            var scopes = _user.Claims.Where(it => it.Type == "scope").Select(it => it.Value).ToList();
            // token返回
            var token = _authService.CreateAccessToken(new UserTokenDto
            {
                Email = string.Empty,
                Id = _user.Id.ToLong(),
                Mobile = _user.MobilePhone.SafeString(),
                RealName = _user.Name.SafeString(),
                Ids = _user.Ids
            }, scopes);
            return new LoginOutput
            {
                Data = new
                {
                    AccessToken = $"Bearer {token}",
                    Expire = _authService.GetExpireInValue(4),
                    RealName = _user.Name.SafeString(),
                    Mobile = _user.MobilePhone.SafeString(),
                    Id = _user.Id
                }
            };
        }
    }
}